/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sales.seesion.stateless;

import accountManagement.entity.Employee;
import accountManagement.entity.Salesman;
import company.entity.Company;
import company.session.stateless.CompanySessionBean;
import finance.creditControl.sessionbean.CreditControlSessionBean;
import finance.util.exception.FinanceException;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import mrp.sessionbean.MRPATPSessionBean;
import mrp.util.exception.MRPException;
import sales.entity.LineItem;
import sales.entity.SalesOrderEntity;
import sales.entity.SalesQuotation;
import sales.util.exception.*;

/**
 *
 * @author ReinForceII
 */
@Stateless
@LocalBean
public class SalesOrderSessionBean {

    @PersistenceContext
    private EntityManager em;
    @EJB
    SalesQuotationSessionBean salesQuotationSessionBean;
    @EJB
    CreditControlSessionBean creditControlSessionBean;
    @EJB
    MRPATPSessionBean mRPATPSessionbean;
    @EJB
    CompanySessionBean companySessionBean;
    @EJB
    PriceManageSessionBean priceManageSessionBean;
    
   
    public void confirmSalesOrder(Salesman salesman, SalesOrderEntity salesOrder) throws SalesmanAmountLimitExceededException, SalesmanNotExistException {

        if (salesman == null) {
            throw new SalesmanNotExistException();
        }
        if (salesman.getAmountLimit() >= salesOrder.getTotalAmount()) {
            salesOrder.setConfirmedBy(salesman);
            salesOrder.setConfirmed(true);
            salesOrder.setDateConfirmed(Calendar.getInstance().getTime());
            saveChanges(salesOrder);
            return;
        }
        throw new SalesmanAmountLimitExceededException();
    }

    public void confirmPendingOrder(Salesman salesman, SalesOrderEntity salesOrder, boolean skip) throws SalesmanAmountLimitExceededException, SalesmanNotExistException {
      System.out.println("*****************1***"); 
        if (salesman == null) {
            throw new SalesmanNotExistException();
        }
        System.out.println("*****************2**"); 
        if (salesman.getAmountLimit() >= salesOrder.getTotalAmount()) { 
            salesOrder.setLargeOrderConfirmedBy(salesman);
            salesOrder.setLargeOrderConfirmed(true);
            saveChanges(salesOrder);
        } else {
            throw new SalesmanAmountLimitExceededException();
        }
        System.out.println("*****************3***"); 
        if (skip && salesOrder.isLargeOrderConfirmed()) {
            salesOrder.setConfirmedBy(salesman);
            salesOrder.setConfirmed(true);
            salesOrder.setDateConfirmed(Calendar.getInstance().getTime());
        }


    }

    /* public Product getProduct(String productName) { //TODO: delete after Oct 3
    Query query = em.createQuery("SELECT p FROM Product p WHERE p.productName = :inProductName");
    query.setParameter("inProductName", productName);
    Product product = null;
    try {
    product = (Product) query.getSingleResult();
    } catch (NoResultException ex) {
    ex.printStackTrace();
    }
    return product;
    }*/
    /*public Company getCustomer(Long id){
    Company customer = em.find(Company.class, id);
    return customer;
    }*/
    public void verifyPurchaseOrder(SalesOrderEntity salesOrder) throws SalesException {

        SalesQuotation salesQuotation = salesOrder.getSalesQuotation();
        if (salesQuotation == null) {
            throw new QuotationNotFoundException();
        }

        if (salesQuotation.getValidUntil().before(Calendar.getInstance().getTime())) {
            throw new QuotationExpiredException();
        }
        priceManageSessionBean.verifySalesOrderPrice(salesOrder);

    }

    public void verifySalesOrder(SalesOrderEntity salesOrder) throws FinanceException, MRPException {

        Company tempCompany = salesOrder.getCustomer();
        if (!tempCompany.getCompanyStatus().equals("Full Customer")) {
            tempCompany.setCompanyStatus("Full Customer");
            companySessionBean.saveChanges(tempCompany);
        }//TODO: Maybe we shall shift this part to account Management module
        creditControlSessionBean.creditCheck(salesOrder);
        mRPATPSessionbean.aTPCheck(salesOrder);

        return;
    }

    private boolean verifyAmountLimit(Salesman salesman, double totalAmount) {

        if (salesman.getAmountLimit() >= totalAmount) {
            return true;
        } else {
            return false;
        }

    }

    public void addSalesOrder(SalesOrderEntity salesOrder) {
        em.persist(salesOrder);
    }

    public void saveChanges(SalesOrderEntity salesOrder) {
        em.merge(salesOrder);
    }

    public void saveChanges(SalesOrderEntity salesOrder, Collection<LineItem> lineItems) {
        /* TODO: How to save changes?
        for (LineItem item : lineItems) {
        em.merge(item);
        }*/
        em.merge(salesOrder);
    }

    public void deleteSalesOrder(Long id) {
        SalesOrderEntity salesOrder = em.find(SalesOrderEntity.class, id);
        em.remove(salesOrder);
    }
   
    
    public List<SalesOrderEntity> getAllPurchaseOrders(Salesman user) throws NoPurchaseOrderException { // Returns only confirmed salesorder
       if(user.getSalesManLevel().equals("4")){
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE sl.largeOrderConfirmed = 1 AND sl.verifiedBySystem = 1");

        List<SalesOrderEntity> salesOrders = null;
        try {
            salesOrders = query.getResultList();
        } catch (NoResultException ex) {
            throw new NoPurchaseOrderException();
        }  
        return salesOrders;
       }
       else{
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE sl.processedBy = :inUserId AND sl.largeOrderConfirmed = 1 AND sl.verifiedBySystem = 1");
        query.setParameter("inUserId",user);
        List<SalesOrderEntity> salesOrders = null;
        try {
            salesOrders = query.getResultList();
        } catch (NoResultException ex) {
            throw new NoPurchaseOrderException();
        }
        return salesOrders;
    }
    }
     public List<SalesOrderEntity> getAllNotVerifiedOrders(Salesman user) throws NoPurchaseOrderException { // Returns only confirmed salesorder
       if(user.getSalesManLevel().equals("4")){
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE  sl.verifiedBySystem = 0 AND sl.largeOrderConfirmed = 1 ");

        List<SalesOrderEntity> salesOrders = null;
        try {
            salesOrders = query.getResultList();
        } catch (NoResultException ex) {
            throw new NoPurchaseOrderException();
        }  
        return salesOrders;
       }
       else{
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE sl.processedBy = :inUserId  AND sl.verifiedBySystem = 0 AND sl.largeOrderConfirmed = 1");
        query.setParameter("inUserId",user);
        List<SalesOrderEntity> salesOrders = null;
        try {
            salesOrders = query.getResultList();
        } catch (NoResultException ex) {
            throw new NoPurchaseOrderException();
        }
        return salesOrders;
    }
    }

    public List<SalesOrderEntity> getAllSalesOrders(Salesman user) throws NoSalesOrderException { // Returns only not confimed salesorder (purchase order)
       if(user.getSalesManLevel().equals("4")){
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE sl.confirmed = 1");

        List<SalesOrderEntity> salesOrders = null;
        try {
            salesOrders = query.getResultList();
        } catch (NoResultException ex) {
            throw new NoSalesOrderException();
        }  
        return salesOrders;
       }
        else{
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE sl.confirmed = 1 AND sl.processedBy = :inUserId");
        query.setParameter("inUserId",user);
        List<SalesOrderEntity> salesOrders = null;

        try {
            salesOrders = query.getResultList();
        } catch (NoResultException e) {
            throw new NoSalesOrderException();
        }
        return salesOrders;
    }
}
    
        public List<SalesOrderEntity> getAllPendingOrders(Salesman user) throws NoPurchaseOrderException { 
            // Returns only not confimed salesorder (purchase order)
        if(user.getSalesManLevel().equals("4")){
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE sl.largeOrderConfirmed = 0 AND sl.verifiedBySystem = 0");

        List<SalesOrderEntity> salesOrders = null;
        try {
            salesOrders = query.getResultList();
        } catch (NoResultException ex) {
            throw new NoPurchaseOrderException();
        }  
        return salesOrders;
       }  else{ 
        Query query = em.createQuery("SELECT sl FROM SalesOrderEntity sl WHERE sl.largeOrderConfirmed = 0 AND sl.processedBy = :inUserId AND sl.verifiedBySystem = 0");
        query.setParameter("inUserId",user);
        List<SalesOrderEntity> salesOrders = null;

        try {
            salesOrders = query.getResultList();
        } catch (NoResultException e) {
            throw new NoPurchaseOrderException();
        }
        return salesOrders;
    }
        }
    //recently changed, retrieve the purchaseOrder

    public SalesOrderEntity getSalesOrderById(Long id) {
        return em.find(SalesOrderEntity.class, id);
    }
}
